home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr05
/
xnot12a.zip
/
TTY.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-21
|
9KB
|
527 lines
/*
* Mg 2b (turboc 1.5/MSC 1.5)
* IBM-PC and compatible BIOS based display driver.
* - this will tend to be a bit slower than a driver that
* writes directly to the memory mapped screen, but with
* the large # of display adapters floating around, I'd
* rather let the bios do the work.
*
* I DO recommend FANSI-CONSOLE which significantly speeds
* up display bios calls, however.
*
* Bashed much to support, among other things, CURSES under U*x
* and pre-queueable input everywhere not WINDOW_IO.
*/
#include "jam.h"
#include "def.h"
#include "keyname.h"
#ifndef CURSES /* UNIX only */
# include <dos.h>
#else
#include <signal.h>
# ifdef SOL
# include <sys/resource.h>
struct rlimit rlim;
# endif
#endif
#define BEL 0x07 /* BEL character. */
#define NORMAL 0x07
#define REVERSE 0x70
extern int ttrow;
extern int ttcol;
extern int tttop;
extern int ttbot;
extern int tthue;
static int biocol = 0;
int tceeol = 2; /* Costs are set later */
int tcinsl = 5;
int tcdell = 5;
static int insdel = TRUE; /* Do we have both insert & delete line? */
static int rendition = NORMAL;
static int rn_(_move, (int row, int col));
static int rn_(_ttinsl,(int row, int bot, int nchunk));
static int rn_(_ttdell, (int row, int bot, int nchunk));
static int rn_(napstart,(int amount,struct nap *sav));
static int rn_(napchk, (struct nap *sav));
static int rn_(nap, (int amount));
static int rn_(putthechar,(unsigned char c));
/*
* Initialize the terminal when the editor
* gets started up.
*/
ttinit()
{
#ifdef CURSES
char *termid = (char *)getenv("TERM");
initscr();
saveterm();
noecho();
nonl();
cbreak();
raw();
halfdelay(2); /* non-blocking i/o at 1/10 sec intervals */
keypad(stdscr, TRUE);
/* Sigh, on some devices the scroll feature looks
* crummy. This should be a list, and also user-setable
*/
idlok(stdscr, TRUE);
if (termid)
{
if ((strcmp("xterm", termid) == 0) || (strcmp("sun-cmd", termid) == 0))
idlok(stdscr, FALSE);
}
wmove(stdscr, 0, 0);
#endif
return 1;
}
/*
* Clean up the terminal, in anticipation of
* a return to the command interpreter.
*/
tttidy()
{
#ifdef CURSES
resetterm();
echo();
nocbreak();
noraw();
nl();
endwin();
#endif
return 1;
}
int ttputline(s)
char *s;
{
while (s && *s)
ttputc(*s++);
return(1);
}
/*
* Move the cursor to the specified
* origin 0 row and column position.
*/
ttmove(row, col)
int row, col;
{
ttcol = col;
ttrow = row;
_move(row, col);
return 1;
}
/*
* Erase to end of page.
*/
tteeop()
{
#ifdef CURSES
wclrtobot(stdscr);
#else
ttdell(ttrow, nrow, nrow - ttrow);
#endif
return 1;
}
/*
* Insert nchunk blank line(s) onto the
* screen, scrolling the last line on the
* screen off the bottom.
*/
ttinsl(row, bot, nchunk)
int row, bot, nchunk;
{
if (row == bot)
{ /* Case of one line insert is */
ttmove(row, 0); /* special */
tteeol();
}
else
_ttinsl(row, bot, nchunk);
return 1;
}
/*
* Delete nchunk line(s) from "row", replacing the
* bottom line on the screen with a blank line.
*/
ttdell(row, bot, nchunk)
int row, bot, nchunk;
{
if (row == bot)
{ /* One line special case */
ttmove(row, 0);
tteeol();
}
else
_ttdell(row, bot, nchunk);
return 1;
}
/*
* Switch to full screen scroll. This is
* used by "spawn.c" just before is suspends the
* editor, and by "display.c" when it is getting ready
* to exit.
*/
ttnowindow()
{
return 1;
}
/*
* Set the current writing color to the
* specified color. Watch for color changes that are
* not going to do anything (the color is already right)
* and don't send anything to the display.
*/
ttcolor(color)
register int color;
{
if (color != tthue)
{
#ifdef CURSES
wrefresh(stdscr);
#endif
if (color == CTEXT)
rendition = NORMAL;
else if (color == CMODE)
rendition = REVERSE;
tthue = color; /* Save the color. */
#ifdef CURSES
if (rendition == CMODE)
wattron(stdscr, A_REVERSE);
else
wattroff(stdscr, A_REVERSE);
#endif
}
return 1;
}
/*
* This routine is called by the
* "refresh the screen" command to try and resize
* the display. The new size, which must be deadstopped
* to not exceed the NROW and NCOL limits, it stored
* back into "nrow" and "ncol". Display can always deal
* with a screen NROW by NCOL. Look in "window.c" to
* see how the caller deals with a change.
*/
ttresize()
{
int flag = 0;
setttysize();
return 1;
}
ttputc(c)
unsigned char c;
{
if (c == '\b')
{
if (biocol-1 > 0)
{
_move(ttrow, biocol-1);
}
return (1);
}
else if (c == '\r')
{
_move(ttrow, 0);
return (1);
}
putthechar(c);
if (biocol+1 >= ncol)
_move(ttrow + 1, 0);
else
_move(ttrow, biocol + 1);
}
/********************* bios calls, or manipulations ******************/
/* Move cursor to row, col. next char goes here
*/
static int _move(row, col)
int row, col;
{
#ifdef CURSES
biocol = col;
wmove(stdscr, row, col);
#else
union REGS rg;
biocol = col;
rg.h.ah = 2; /* set cursor position function code */
rg.h.dl = col;
rg.h.dh = row;
rg.h.bh = 0; /* set screen page number */
int86(0x10, &rg, &rg);
#endif
return 1;
}
/*
* Erase to end of line.
*/
tteeol()
{
#ifdef CURSES
wclrtoeol(stdscr);
#else
union REGS rg;
rg.h.ah = 9; /* write character/rendition */
rg.h.bh = 0;
rg.x.cx = ncol-biocol;
rg.h.al = ' ';
rg.h.bl = rendition;
int86(0x10, &rg, &rg);
#endif
return 1;
}
/*
* Make a noise.
*/
ttbeep()
{
#ifdef CURSES
beep();
#else
# if 0
union REGS rg;
rg.h.ah = 14; /* write tty */
rg.h.al = BEL;
int86(0x10, &rg, &rg);
# else
ewprintf("BEEP BEEP!"); /* bios bell is TOO LONG AND LOUD */
# endif
#endif
return 1;
}
/*
* Insert nchunk blank line(s) onto the
* screen, scrolling the last line on the
* screen off the bottom.
*/
static int _ttinsl(row, bot, nchunk)
int row, bot, nchunk;
{
#ifdef CURSES
printf("_ttinsl NYI\n");
#else
union REGS rg;
rg.h.ah = 7; /* scroll down */
rg.h.bh = 0x07;
rg.h.al = nchunk;
rg.h.ch = row;
rg.h.cl = 0;
rg.h.dh = bot;
rg.h.dl = ncol - 1;
int86(0x10, &rg, &rg);
#endif
return 1;
}
/*
* Delete nchunk line(s) from "row", replacing the
* bottom line on the screen with a blank line.
*/
static int _ttdell(row, bot, nchunk)
int row, bot, nchunk;
{
#ifdef CURSES
printf("_ttdell NYI\n");
#else
union REGS rg;
rg.h.ah = 6; /* scroll up */
rg.h.bh = 0x07;
rg.h.al = nchunk;
rg.h.ch = row;
rg.h.cl = 0;
rg.h.dh = bot;
rg.h.dl = ncol - 1;
int86(0x10, &rg, &rg);
#endif
return 1;
}
static int putthechar(c)
unsigned char c;
{
#ifdef CURSES
waddch(stdscr, c);
#else
union REGS rg;
rg.h.ah = 9; /* write character/rendition */
rg.h.bh = 0;
rg.x.cx = 1;
rg.h.al = c;
rg.h.bl = rendition;
int86(0x10, &rg, &rg);
#endif
return 1;
}
#ifdef MSC
/***************************/
/* MSDOS time functions */
/***************************/
/* waiting thing...
*/
struct nap
{
long napvalue;
long basetime;
};
/* Apparantly Turbo C has a sleep library routine; MSC doesn't -jbs */
#define gettime(_a) ((((long)(_a.x.cx)) << 16)+_a.x.dx)
void sleep(amount)
int amount;
{
while (amount--)
# if 1
nap(50); /* not so long! */
# else
nap(100);
# endif
}
/* nap in units of 100ths of seconds via busy loops.
*/
static int nap(amount)
int amount;
{
struct nap tim;
napstart(amount, &tim);
while(napchk(&tim) == 0)
;
return 1;
}
static int napstart(amount,sav)
int amount;
register struct nap *sav;
{
union REGS inregs, outregs;
int hunds, secs;
inregs.h.ah = 0x2c; /* get time */
int86(0x21, &inregs, &outregs);
/* glitch in hardware RTC (time warp) makes this necessary
*/
inregs = outregs;
inregs.h.dl = 0; /* seconds counter may be slow to increment */
if (inregs.h.dh > 0)
--inregs.h.dh; /* paranoia */
if (inregs.h.cl > 0)
--inregs.h.cl; /* more paranoia */
/* end of glitch handling */
sav->basetime = gettime(inregs); /* in case of wraparound */
/* convert hundredths of seconds to future time structure
*/
secs = outregs.h.dh;
hunds = outregs.h.dl + amount;
while (hunds >= 100)
{
hunds -= 100;
++secs;
}
outregs.h.dl = hunds;
while (secs >= 60)
{
secs -= 60;
++outregs.h.cl; /* increment minutes */
}
outregs.h.dh = secs;
/* check for minute and hour wraparound
*/
if (outregs.h.cl >= 60)
{
outregs.h.cl -= 60;
++outregs.h.ch; /* increment hours */
}
if (outregs.h.ch >= 24)
{
outregs.h.ch -= 24;
}
sav->napvalue = gettime(outregs);
return 1;
}
static int napchk(sav)
register struct nap *sav;
{
union REGS inregs, outregs;
long current;
inregs.h.ah = 0x2c; /* get time */
int86(0x21, &inregs, &outregs);
current = gettime(outregs);
if(sav->napvalue > sav->basetime)
{
if (current >= sav->napvalue || current < sav->basetime)
return 1;
}
else if (current >= sav->napvalue && current < sav->basetime)
return 1;
return 0;
}
#endif /* MSC */
ttwait()
{
#ifndef CURSES
struct nap timer;
napstart(200, &timer);
while (napchk(&timer) == 0)
#endif
if (mytypeahead())
return 0;
return 1;
}